package com.motong.gongdan.controller.system;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.motong.gongdan.config.ResponseData;
import com.motong.gongdan.config.auth.UserLoginToken;
import com.motong.gongdan.config.wechat.ConfigurationService;
import com.motong.gongdan.entity.CustomEvent;
import com.motong.gongdan.entity.Departments;
import com.motong.gongdan.entity.User;
import com.motong.gongdan.job.QuartzBean;
import com.motong.gongdan.service.*;
import com.motong.gongdan.util.LoginUtil;
import com.motong.gongdan.util.QuartzUtil;
import com.motong.gongdan.util.StringUtil;
import com.motong.gongdan.vo.system.otherVo.CustomEventListVo;
import com.motong.gongdan.vo.system.otherVo.IdVo;
import com.motong.gongdan.vo.customEvent.SearchVo;
import com.motong.gongdan.vo.resp.EventLogResp;
import com.motong.gongdan.vo.system.CustomEvent.MissionEventMsg;
import com.motong.gongdan.vo.system.CustomEvent.WorkOrderEventMsg;
import com.motong.gongdan.vo.system.CustomEvent.WorkReportEventMsg;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.quartz.Scheduler;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author:fff
 * @time:2022/5/16
 */
@Api(value = "自定义事件", tags = {"自定义事件"})
@RestController
@RequestMapping("/sys/custom_event/")
public class CustomEventController {
    @Resource
    CustomEventService customEventService;
    @Resource
    EventLogService eventLogService;
    @Resource
    UserService userService;
    @Resource
    DepartmentsService departmentsService;
    @Resource
    private Scheduler scheduler;
    @Resource
    WorkOrderService workOrderService;

    @UserLoginToken
    @ApiOperation(value = "自定义事件列表")
    @RequestMapping(value = "list", method = RequestMethod.POST)
    public ResponseData list(@RequestBody CustomEventListVo vo) {
        QueryWrapper<CustomEvent> qw = new QueryWrapper<CustomEvent>()
                .like(StringUtil.isNotBlank(vo.getName()), "name", vo.getName())
                .eq(vo.getState() != null, "state", vo.getState())
                .eq(vo.getType() != null, "event_type", vo.getType()).eq("type", vo.getListType());
        Page<CustomEvent> data = customEventService.page(new Page<>(vo.getPage(), vo.getLimit()), qw);
        if (!CollectionUtils.isEmpty(data.getRecords())) {
            data.getRecords().forEach(d -> {
                d.setName(d.getName().replace(":" + LoginUtil.getLoginUserFactory(), ""));
                if (d.getCustomType() == 0) {
                    d.setEventContent("");
                    String a = "";
                    if (d.getCustomDataType() == 0) {
                        a = a + "新增数据后";
                    } else if (d.getCustomDataType() == 1) {
                        a = a + "编辑数据后";
                    } else {
                        a = a + "删除数据后";
                    }
                    a = a + ", 当满足触发事件条件时，执行";
                    if (d.getType() == 0) {
                        a = a + "公众号-消息推送。";
                    } else if (d.getType() == 1) {
                        if (d.getEventType() == 0) {
                            a = a + "公众号-消息推送。";
                        } else if (d.getEventType() == 1) {
                            if (d.getExecuteForm() == 0) {
                                a = a + "工单中设置的执行事件条件。";
                            } else {
                                a = a + "任务中设置的执行事件条件。";
                            }
                        }
                    }
                    d.setEventContent(a);
                }
                if (StringUtil.isNotBlank(d.getPushMess())) {
                    if (d.getType() == 0) {
                        d.setPushMessVo(JSONUtil.toBean(d.getPushMess(), WorkOrderEventMsg.class));
                    } else if (d.getType() == 1) {
                        d.setMissionPushMessVo(JSONUtil.toBean(d.getPushMess(), MissionEventMsg.class));
                    } else {
                        d.setWorkReportPushMessVo(JSONUtil.toBean(d.getPushMess(), WorkReportEventMsg.class));
                    }
                }
                if (StringUtils.hasLength(d.getSearchCondition())) {
                    d.setSearchVo(JSONUtil.toList(d.getSearchCondition(), SearchVo.class));
                }
                if (StringUtils.hasLength(d.getStatisticsData())) {
                    d.setStatisticsDataMap(JSONUtil.toBean(d.getStatisticsData(), Map.class));
                }
                if (StringUtils.hasLength(d.getUserId())) {
                    List<String> userIds = Arrays.asList(d.getUserId().split(","));
                    LambdaQueryWrapper<User> userQw = new LambdaQueryWrapper<User>().select(User::getName).in(User::getId, CollectionUtils.isEmpty(userIds) ? Collections.singletonList(-1) : userIds);
                    String userNames = userService.list(userQw).stream().map(User::getName).collect(Collectors.joining(","));
                    d.setUserNames(userNames);
                }
                if (StringUtils.hasLength(d.getDepId())) {
                    List<String> deptIds = Arrays.asList(d.getDepId().split(","));
                    LambdaQueryWrapper<Departments> deptQw = new LambdaQueryWrapper<Departments>().select(Departments::getName).in(Departments::getId, CollectionUtils.isEmpty(deptIds) ? Collections.singletonList(-1) : deptIds);
                    String deptNames = departmentsService.list(deptQw).stream().map(Departments::getName).collect(Collectors.joining(","));
                    d.setDepNames(deptNames);
                }

            });
        }
        return ResponseData.success(data);
    }

    @UserLoginToken
    @ApiOperation(value = "新增/编辑")
    @PostMapping("handle")
    public ResponseData<?> handle(@RequestBody CustomEvent vo) {
        boolean isUpdate = Objects.nonNull(vo.getId());
        // 判重
        if (StringUtils.hasLength(vo.getName())) {
            LambdaQueryWrapper<CustomEvent> repeatQW = new LambdaQueryWrapper<CustomEvent>().eq(CustomEvent::getName, vo.getName()).ne(isUpdate, CustomEvent::getId, vo.getId());
            if (customEventService.count(repeatQW) > 0) {
                return ResponseData.fail(500, "名称不能重复");
            }
            vo.setName(vo.getName() + ":" + LoginUtil.getLoginUserFactory());
        }
        if (isUpdate) {
            CustomEvent oriData = customEventService.getOne(new QueryWrapper<CustomEvent>().eq("id", vo.getId()).eq("custom_type", 1));
            if (oriData != null) {
                QuartzUtil.deleteScheduleJob(scheduler, oriData.getName());
            }
        }
        vo.setPushMess(Objects.nonNull(vo.getPushMessVo()) ? JSONUtil.toJsonStr(vo.getPushMessVo()) : null);
        vo.setPushMess(Objects.nonNull(vo.getMissionPushMessVo()) ? JSONUtil.toJsonStr(vo.getMissionPushMessVo()) : vo.getPushMess());
        vo.setPushMess(Objects.nonNull(vo.getWorkReportPushMessVo()) ? JSONUtil.toJsonStr(vo.getWorkReportPushMessVo()) : vo.getPushMess());
        vo.setSearchCondition(Objects.nonNull(vo.getSearchVo()) ? JSONUtil.toJsonStr(vo.getSearchVo()) : null);
        //map key ${工单.统计数据1。。。。}
        vo.setStatisticsData(Objects.nonNull(vo.getStatisticsDataMap()) ? JSONUtil.toJsonStr(vo.getStatisticsDataMap()) : null);
        customEventService.saveOrUpdate(vo);
        if (vo.getCustomType() != null && vo.getCustomType() == 1) {
            QuartzBean qb = customEventService.handleEventTime(vo);
            QuartzUtil.createScheduleJob(scheduler, qb);
        }
        return ResponseData.success(ResponseData.Status.SUCCESS);
    }

    @UserLoginToken
    @ApiOperation(value = "删除")
    @RequestMapping(value = "del", method = RequestMethod.POST)
    public ResponseData<?> del(@RequestBody IdVo vo) {
        CustomEvent ce = customEventService.getById(vo.getId());
        customEventService.removeById(vo.getId());
        if (ce.getCustomType() == 1) {
            QuartzUtil.deleteScheduleJob(scheduler, ce.getName());
        }
        return ResponseData.success(ResponseData.Status.SUCCESS);
    }

    @UserLoginToken
    @ApiOperation(value = "执行日志")
    @RequestMapping(value = "log", method = RequestMethod.POST)
    public ResponseData<?> log(@RequestBody CustomEventListVo vo) {
        IPage<EventLogResp> data = customEventService.getBaseMapper().getEventLog(new Page(vo.getPage(), vo.getLimit()), new QueryWrapper<EventLogResp>()
                .like(StringUtil.isNotBlank(vo.getName()), "ce.name", vo.getName())
                .eq(vo.getState() != null, "e.state", vo.getState())
                .eq(vo.getType() != null, "ce.type", vo.getType())
                .between(vo.getStartTime() != null && vo.getEndTime() != null, "e.time", vo.getStartTime(), vo.getEndTime())
                .orderByDesc("e.id"));
        if (!CollectionUtils.isEmpty(data.getRecords())) {
            data.getRecords().forEach(d -> {
                if (StringUtil.isNotBlank(d.getUser())) {
                    List<User> userList = userService.listByIds(Arrays.asList(d.getUser().split(",")));
                    d.setUser(userList.stream().map(User::getName).collect(Collectors.joining(",")));
                    d.setUserRole(userList.stream().map(User::getRole).collect(Collectors.joining(",")));
                }
            });
        }
        return ResponseData.success(data);
    }

    @UserLoginToken
    @ApiOperation(value = "执行日志详情")
    @RequestMapping(value = "log_detail", method = RequestMethod.POST)
    public ResponseData logDetail(@RequestBody IdVo vo) {
        EventLogResp data = customEventService.getBaseMapper().getOneById(new QueryWrapper<EventLogResp>().eq("e.id", vo.getId()));
        if (data != null && StringUtils.hasLength(data.getUser())) {
            List<String> userIds = Arrays.asList(data.getUser().split(","));
            List<User> userList = userService.listByIds(userIds);
            if (!CollectionUtils.isEmpty(userList)) {
                data.setUserRole(userList.stream().map(User::getName).collect(Collectors.joining(",")));
                data.setUser(userList.stream().map(User::getRole).collect(Collectors.joining(",")));
            }
        }
        return ResponseData.success(data);
    }

    @Resource
    ConfigurationService configurationService;

    @UserLoginToken
    @RequestMapping(value = "test", method = RequestMethod.POST)
    public ResponseData test() {
        cn.hutool.json.JSONObject jo = configurationService.getAccessToken();
        String token = jo.getStr("access_token");
        System.out.println(token);
        cn.hutool.json.JSONObject joo = configurationService.getUserList(token);
        return ResponseData.success(joo);
    }
}
